<?php

declare(ENCODING = 'UTF-8');

/*                                                                        *
 * This script is part of the TYPO3 project - inspiring people to share!  *
 *                                                                        *
 * TYPO3 is free software; you can redistribute it and/or modify it under *
 * the terms of the GNU General Public License version 2 as published by  *
 * the Free Software Foundation.                                          *
 *                                                                        *
 * This script is distributed in the hope that it will be useful, but     *
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *	
 * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General      *
 * Public License for more details.                                       *
 *                                                                        */	

/**
 * @package auxo
 * @subpackage Component
 * @version $Id$
 */

/**	
 * The Component Parameter Argument Mapper
 *	
 * @package auxo
 * @subpackage Component
 * @version $Id$	
 * @copyright Copyright belongs to the respective authors
 * @author AHN
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License, version 2
 */
class tx_auxo_ComponentParameterArgumentMapper {
	
	/**
	 * A Component Factory
	 *
	 * @var tx_auxo_ComponentFactory
	 */
	private $factory = NULL;
	
	/**
	 * Creates a new Mapper 
	 *
	 * @param unknown_type $factory
	 */
	public function __construct($factory) {
		$this->factory = $factory;
	}
	
	/**
	 * Maps configurations parameters to method arguments
	 *
	 * @param array $parameters an array of parameters instances (tx_auxo_ComponentConfigurationParamter)
	 * @return array $arguments array of arguments ready for injection
	 */
	public function map($parameters) {
		debug($parameters, 'parameters');
		$arguments = array();
		/* arguments is an array of arrayObject */
		foreach($parameters as $name => $parameter) {
			$arguments[$name] = $this->mapParameterToArgument($parameter);
		}	
		return $arguments;	
	}
	
	/**
	 * Maps a single parameter to an method argument
	 *
	 * @param mixed $parameter parameter
	 * @return mixed $argument mapped argument or null 
	 */
	private function mapParameterToArgument($parameter) {
		if (! $parameter instanceof tx_auxo_ComponentConfigurationParameter) {
			return $parameter;
		}
		switch($parameter->getType()) {		
			case tx_auxo_ComponentConfigurationParameter::TYPE_CLASSREF:
				//TODO class reference currently could not be created via get -> new method needed
				throw new tx_auxo_UnSupportedFeatureException(sprintf('Class References %s could not be handled currently', $value->getData()));
				break;			
			case tx_auxo_ComponentConfigurationParameter::TYPE_REF:
				return $this->factory->get($parameter->getData());
				break;
			case tx_auxo_ComponentConfigurationParameter::TYPE_HASH:						
				return new tx_auxo_HashArray($this->mapArray($parameter->getData()));
				break;
			case tx_auxo_ComponentConfigurationParameter::TYPE_SET:
				return new tx_auxo_ArrayObject($this->mapArray($parameter->getData()));
				break;
			case tx_auxo_ComponentConfigurationParameter::TYPE_ARRAY:
				return $this->mapArray($parameter->getData());
				break;						
			default:
				return $parameter->getData();
				break;		
		}
	
		return NULL;
	}

	/**
	 * Maps an array parameters with its elements to an argument
	 * 
	 * Traverses all array parameters and maps them by type. Nested arrays 
	 * are supported.
	 *
	 * @param mixed $array a parameter array of type tx_auxo_ComponentConfigurationParameter
	 * @param array $mapped mapped argument as array
	 */
	private function mapArray($array) {
		$mapped = array();
		//TODO prepare array element for injection
		foreach($array as $index => $value) {
			$mapped[$index] = $this->mapParameterToArgument($value);
		}		
		return $mapped;
	}
}
?>